<template>
  <div class="h-100 relative">
    <div class="map-switcher flex">
      <slot name="operateBtn" />
      <gis-search v-if="showType === 'regionLocate'" @locatePoint="setCenter" />
      <el-button
        v-if="showType === 'regionLocate' && !draw && operateType !== 'view'"
        class="locate-btn"
        type="primary"
        size="mini"
        icon="el-icon-location-outline"
        @click="drawClick"
      >{{ $t('LOCATION') }}</el-button>
    </div>
    <div
      v-if="!previewStatisicsName"
      class="zoom-tools flex-column align-center pointer text-color"
      :class="fullScreen || showType !== 'home' ? 'full-screen' : ''"
    >
      <!-- <div class="tool-item  border-radus">
        <i class="el-icon-aim tool-item" @click="$debounce(locateCur)" />
      </div> -->
      <div class="zoom-btn flex-column align-center border-radus mt-5">
        <i class="el-icon-plus tool-item" @click="$debounce(changeZoom, +1)" />
        <i class="el-icon-minus tool-item" @click="$debounce(changeZoom, -1)" />
      </div>
      <div class="tool-item mt-5 border-radus">
        <span
          v-if="sourceType === 'vector' && mapConfig.vectorLayer.source && mapConfig.onlineMap"
          @click="changeMapType('satellite')"
        >{{ $t('SATELLITE') }}</span>
        <span
          v-if="
            sourceType === 'satellite' &&
              (mapConfig.satelliteLayer.source || mapConfig.satelliteMarkLayer.source) &&
              mapConfig.onlineMap
          "
          @click="changeMapType('vector')"
        >{{ $t('VECTOR_QUANTITY') }}</span>
      </div>
      <div
        v-if="sourceType !== 'satellite' && mapConfig.vectorLayer.source"
        class="tool-item mt-5 font-mini border-radus"
      >
        <span v-if="sourceType === 'darkblue'" @click="changeMapType('vector')">{{
          $t('LIGHT_COLOR')
        }}</span>
        <span v-else @click="changeMapType('darkblue')">{{ $t('DEEP_COLOR') }}</span>
      </div>
    </div>
    <div :id="mapId" ref="gisMap" class="w-100 h-100 openlayerMap" />
    <div class="absolute cluster-prop" :style="clusterInfo.position">
      {{ clusterInfo.content }}
    </div>
    <facility-detail
      v-show="mapHoverType === 'facilityHover'"
      :style="hoverPosition"
      :params="currentData"
      class="absolute"
    />
    <!-- 编辑光缆段 -->
    <edit-cable
      :visible="cableSegmentShow"
      :row-data="cableData"
      :type="cableSegmentOperateType"
      :cable-list="curCableSegment"
      @close="updateData"
    />
  </div>
</template>

<script>
  import { intersection } from 'lodash'
  import 'ol/ol.css'
  import { Vector as VectorSource } from 'ol/source'
  import { Draw, Select, Translate, Modify } from 'ol/interaction'
  import { Stroke, Style } from 'ol/style'
  import { LineString } from 'ol/geom'
  import Collection from 'ol/Collection'
  import mixin from './mixin'
  import { click } from 'ol/events/condition'
  import regionApi from '@/api/basebiz/RegionApi'
  import cableSegmentApi from '@/api/oen/CableSegmentApi'
  import facilityApi from '@/api/oen/FacilityApi'
  import { changeDecimal, deepClone } from '@/utils/common'
  import { mapGetters } from 'vuex'
  import FacilityDetail from './components/FacilityDetail'
  import EditCable from '@/views/module/conf/cable/EditCable'
  import GisSearch from '../map/components/GisSearch'
  import { getDistance } from 'ol/sphere'
  const mapConfig = window.__mapConfig__

  export default {
    components: {
      EditCable,
      FacilityDetail,
      GisSearch
    },
    mixins: [mixin],
    props: {
      nodes: {
        type: Array,
        default: () => []
      },
      edges: {
        type: Array,
        default: () => []
      },
      operateType: {
        type: String,
        default: ''
      },
      showType: {
        type: String,
        default: ''
      },
      isEdit: {
        type: Boolean,
        default: false
      },
      mapId: {
        type: String,
        default: 'gisMap'
      },
      staticsItem: {
        type: Object,
        default: () => {
          return {
            width: 0,
            height: 0
          }
        }
      },
      previewStatisicsName: {
        type: String,
        default: ''
      },
      selectedAll: {
        // 判断当前区域筛选是否是全选
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        map: null,
        sourceType: 'vector',
        center: [116.397083, 39.874531], // 北京
        offlineLayer: null,
        stationLayer: null,
        cableLayer: null,
        facilityLayer: null,
        clusterLayer: null,
        navLayer: null,
        drawLayer: null,
        hoverLineFeature: null,
        hightLightEdges: [],
        mapReady: false,
        dataReady: false,
        eventReady: false,
        draw: null,
        dragging: false,
        draggableCollection: null, // 可拖拽的要素放置到此序列
        facilityList: [],
        cableSegmentList: [],
        zoom: 4,
        clusterInfo: {
          position: {
            top: 0,
            left: 0,
            display: 'none'
          },
          content: ''
        },
        facilityData: {},
        movingCable: [],
        cableData: {},
        cableSegmentShow: false,
        mapHoverType: '',
        currentData: {},
        hoverPosition: {
          left: 0,
          right: 0,
          bottom: 0
        },
        mapConfig: mapConfig,
        isUpDate: false,
        modifyLine: null,
        modifyData: null,
        layingMethodFilter: {
          enable: false,
          cableIds: [],
          facilityIds: []
        },
        isModLocation: false,
        locationChangeData: {},
        curCableSegment: [],
        cableSegmentOperateType: 'edit',
        unBindFacilityData: null
      }
    },
    computed: {
      ...mapGetters([
        'dictList',
        'stationSelected',
        'gisActived',
        'cableLevelSelected',
        'fullScreen',
        'baseRegionList',
        'hideAlarmLevel',
        'facilityVisiable',
        'layingMethodSelected',
        'filterStationIds',
        'getTheme',
        'indexShowRight',
        'needFitView',
        'curZoom'
      ]),
      viewPadding() {
        let left = 50
        if (this.operateType !== '') {
          left = 450
        }
        return this.fullScreen
          ? [50, 50, 50, left]
          : [
            50,
            this.staticsItem.width + 50,
            this.staticsItem.height + 50,
            this.staticsItem.width + 50
          ]
      }
    },
    watch: {
      hoverLineFeature: function(newVal, oldVal) {
        // console.log('oldVal', oldVal)
        if (oldVal) {
          const isActive = this.gisActived.cableIds.includes(oldVal.values_.data.cableId)
          oldVal.setStyle(
            this.lineStyle(oldVal.values_.data, isActive, isActive ? this.gisActived.color : null)
          )
        }
        newVal && newVal.setStyle(this.lineStyle(newVal.values_.data, true, null, true))
      },
      nodes() {
        this.isUpDate = false
        if (this.isEdit) return
        this.formateData()
      },
      stationSelected(newVal, oldVal) {
        if (
          newVal.includes('newRegion') ||
          oldVal.includes('newRegion') ||
          this.showType === 'regionLocate'
        ) {
          return
        }
        this.isUpDate = false
        this.renderMap()
      },
      cableLevelSelected() {
        this.isUpDate = false
        this.renderMap()
      },
      gisActived() {
        this.isUpDate = false
        this.renderMap()
      },
      hideAlarmLevel(newVal) {
        if (this.isEdit) return
        this.isUpDate = false
        this.renderMap()
      },
      zoom(newVal) {
        this.$emit('zoomChange', newVal)
        this.zoomChange()
      },
      facilityVisiable(newVal) {
        this.facilityLayer.setVisible(newVal)
      },
      layingMethodSelected(newVal) {
        this.layingMethodChange(newVal)
      },
      fullScreen(newVal) {
        this.rightClick()
        if (newVal) {
          const mainBox = this.map.getViewport()
          const rect = mainBox.getBoundingClientRect()
          const rightTopCoordinate = this.map.getCoordinateFromPixel([
            rect.right - this.staticsItem.width,
            0
          ])
          const leftBottomCoordinate = this.map.getCoordinateFromPixel([
            rect.left + this.staticsItem.width,
            rect.height - this.staticsItem.height
          ])
          const loaction = [...leftBottomCoordinate, ...rightTopCoordinate]
          this.map.getView().fit(loaction, {
            padding: [0, 0, 0, 0]
          })
        } else {
          const view = this.map.getView()
          const size = this.map.getSize()
          const loaction = view.calculateExtent(size)
          this.map.getView().fit(loaction, {
            padding: [0, this.staticsItem.width, this.staticsItem.height, this.staticsItem.width]
          })
        }
      },
      getTheme(newVal) {
        this.localThemeType()
        // 切换主题 保持站点状态等颜色不变
        this.formateData()
      }
    },
    mounted() {
      this.initMap()
      const showType = ['home', 'cableEidt', 'faultLocation']
      if (showType.includes(this.showType)) {
        this.getInfos()
      }
    },
    methods: {
      hoverLine(cableId) {
        this.hoverLineFeature = this.cableLayer.getSource().getFeatureById(cableId)
      },
      localThemeType() {
        this.getTheme === 'dark-theme' &&
          this.sourceType === 'vector' &&
          this.changeMapType('darkblue')
        this.getTheme !== 'dark-theme' &&
          this.sourceType === 'darkblue' &&
          this.changeMapType('vector')
      },
      // 光缆敷设方式改变数据处理
      layingMethodChange(newVal) {
        // console.log('layingMethodChange', newVal)
        // console.log('edges', this.edges)
        this.$store.commit('setGisActived', {
          cableIds: [],
          nodeIds: [],
          color: ''
        })
        this.layingMethodFilter = {
          enable: false,
          cableIds: [],
          facilityIds: []
        }
        if (newVal.length === 0 || newVal.length === this.dictList.LAYING_METHOD.length + 1) {
          this.$store.commit('setStationSelected', this.filterStationIds)
          return
        }
        const cableIds = []
        const nodeIds = []
        let visibleFacilityIds = []
        this.edges.forEach(i => {
          if (intersection(newVal, i.layingMethod).length) {
            cableIds.push(i.cableId)
            nodeIds.push(i.fromNodeId)
            nodeIds.push(i.toNodeId)
            visibleFacilityIds = [...visibleFacilityIds, ...i.facilityIds]
          }
        })
        this.$store.commit(
          'setStationSelected',
          nodeIds.filter(i => this.filterStationIds.includes(i))
        )
        this.layingMethodFilter = {
          enable: true,
          cableIds: cableIds,
          facilityIds: visibleFacilityIds
        }
      },
      // 获取地理节点、光缆段数据
      getInfos(needRender = true) {
        this.facilityList = []
        this.cableSegmentList = []
        Promise.all([cableSegmentApi.list(), facilityApi.list()])
          .then(([res1, res2]) => {
            this.facilityList = res2
            this.cableSegmentList = res1.sort((a, b) => a.sort - b.sort)
            // console.log('this.cableSegmentList--------', this.facilityList, this.cableSegmentList)
            this.formateData(needRender)
          })
          .catch(err => {
            console.log(err)
          })
      },
      // 组织数据结构，光缆关联相关的光缆段、地理节点
      formateData(needRender = true) {
        const facilityData = {}
        this.facilityList.forEach(i => {
          i.location = [i.longitude, i.latitude]
          facilityData[i.facilityId] = i
        })
        this.nodes.forEach(i => {
          i.location = [i.longitude, i.latitude]
          facilityData[i.nodeId] = i
        })
        this.facilityData = facilityData
        // console.log('设施-----------', this.facilityData)
        this.edges.forEach(j => {
          const cableSegment = this.cableSegmentList.filter(k => j.cableId === k.cableId)
          const cableSegmentIds = []
          const facilityIds = []
          const path = []
          const layingMethod = []
          cableSegment.forEach(k => {
            cableSegmentIds.push(k.segmentId)
            const facility1 = facilityData[k.startPointId]
            if (facility1 && !facilityIds.includes(k.startPointId)) {
              path.push([facility1.longitude, facility1.latitude])
              facilityIds.push(k.startPointId)
            }
            const facility2 = facilityData[k.endPointId]
            if (facility2 && !facilityIds.includes(k.endPointId)) {
              path.push([facility2.longitude, facility2.latitude])
              facilityIds.push(k.endPointId)
            }
            k.startPointName = facility1.label || facility1.facilityName || ''
            k.endPointName = facility2.label || facility2.facilityName || ''
            k.cableName = j.label
            const distance = getDistance(
              [facility1.longitude, facility1.latitude],
              [facility2.longitude, facility2.latitude]
            )
            k.distance = changeDecimal(distance / 1000, 3)
            layingMethod.push(k.erectMethod || 'UNDEFINED')
          })
          const layingMethodList = Array.from(new Set([...layingMethod]))
          j.layingMethod = layingMethodList.length ? layingMethodList : ['UNDEFINED']
          j.cableSegmentIds = cableSegmentIds
          if (path.length) {
            j.facilityIds = facilityIds
            j.path = path
          } else {
            j.facilityIds = [j.fromNodeId, j.toNodeId]
            j.path = [facilityData[j.fromNodeId].location, facilityData[j.toNodeId].location]
          }
        })
        this.dataReady = true
        needRender && this.renderMap()
      },
      // 渲染地图覆盖物
      renderMap() {
        // console.log('this.nodes', this.nodes)
        if (!this.mapReady || !this.dataReady) return
        this.clearDrag()
        this.removeModifyLine()
        this.removeDraw()
        this.stationLayer.getSource().clear()
        this.cableLayer.getSource().clear()
        this.facilityLayer.getSource().clear()
        this.clusterLayer.getSource().getSource().clear()
        this.navLayer && this.navLayer.getSource().clear()

        this.addStations()
        this.addEdges()
        this.zoomChange()
      },
      // 添加站点、聚合点显示到地图；添加事件；
      addStations() {
        const stationData = []
        const activatedNodes = []
        const storeActiveNodes = this.gisActived.nodeIds
        const nodeList = deepClone(this.nodes)
        if (storeActiveNodes.length) {
          nodeList.sort((a, b) => (storeActiveNodes.includes(a.nodeId) ? 1 : -1))
        }
        nodeList.forEach(i => {
          if (this.stationSelected.includes(i.nodeId)) {
            i.location = i.longitude && i.latitude ? [i.longitude, i.latitude] : [...this.center]
            let highLight = false
            let color = null
            if (storeActiveNodes.includes(i.nodeId)) {
              activatedNodes.push(i.nodeId)
              highLight = this.gisActived.filterType !== 'CABLE' // 如果是光缆筛选不需要高亮站点
              color = this.gisActived.color
            }
            stationData.push(this.createStation(i, highLight, color))
          }
        })
        // console.log('stationData', stationData)

        // 将标注要素添加到矢量图层中
        this.stationLayer.getSource().addFeatures(stationData)
        this.clusterLayer.getSource().getSource().addFeatures(stationData)

        !this.eventReady && this.setEventHandler()
        // console.log('activatedNodes', activatedNodes)
        if (
          activatedNodes.length === 1 &&
          !this.gisActived.noMove &&
          this.gisActived.mapId === this.mapId
        ) {
          const nodeData = this.nodes.find(i => i.nodeId === activatedNodes[0])
          if (nodeData) {
            const mapCenter = this.map.getView().getCenter()
            const zoom = this.zoom
            if (zoom !== 12) {
              this.map.getView().animate({ center: nodeData.location, zoom: 12 }, () => {
                !this.fullScreen && this.panByPixel(nodeData.location, mapCenter)
              })
            } else {
              !this.fullScreen && this.panByPixel(nodeData.location, mapCenter)
            }
          }
        }
        if (activatedNodes.length > 1) {
          this.fitView(activatedNodes)
        }
      },
      // 添加光缆显示到地图
      addEdges() {
        const lineData = []
        const filterData =
          this.showType === 'faultLocation' ? [...this.stationSelected] : [...this.filterStationIds]
        const storeActiveCables = this.gisActived.cableIds
        // const edgesList = deepClone(this.edges)
        const edgesList = this.edges
        if (storeActiveCables.length) {
          edgesList.sort((a, b) => (storeActiveCables.includes(a.cableId) ? 1 : -1))
        }
        if (
          this.layingMethodSelected.length &&
          this.layingMethodSelected.length < this.dictList.LAYING_METHOD.length + 1
        ) {
          edgesList.sort((a, b) =>
            intersection(this.layingMethodSelected, a.layingMethod).length ? 1 : -1
          )
        }

        edgesList.forEach(i => {
          if (
            filterData.includes(i.fromNodeId) &&
            filterData.includes(i.toNodeId) &&
            this.cableLevelSelected.includes(i.cableLevel)
          ) {
            let highLight = false
            let color = null
            if (storeActiveCables.includes(i.cableId)) {
              highLight = true
              color = this.gisActived.color
            }
            lineData.push(this.createLineString(i, highLight, color))
          }
        })
        this.cableLayer.getSource().addFeatures(lineData)
      },
      setEventHandler() {
        this.eventReady = true
        this.moveEvent()
        if (this.showType === 'faultLocation') return
        this.leftClick()
        this.addDragEvent()
        if (this.showType === 'regionLocate') return
        this.pointerHover()
        this.selectEvent()
        this.rightClick()
      },
      // 添加拖拽事件
      addDragEvent() {
        // 添加拖拽事件
        this.draggableCollection = new Collection()
        const translate = new Translate({
          features: this.draggableCollection
        })
        this.map.addInteraction(translate)
        translate.on('translatestart', ({ features }) => {
          this.dragging = true
          this.$store.commit('setFullScreen', true)
        })
        translate.on('translating', ({ features }) => {
          const featureList = this.draggableCollection.getArray()
          if (featureList.length) {
            const feature = featureList[0]
            const featureData = feature.values_.data
            const stationCoordinates = feature.getGeometry().getCoordinates()
            const cableLayers = this.cableLayer.getSource().getFeatures()
            cableLayers.forEach(item => {
              const lineGeometry = item.getGeometry()
              const coordinates = lineGeometry.getCoordinates()
              const data = item.values_.data

              // 说明现在移动的是设施
              if (featureData.facilityType) {
                const index = data.facilityIds.indexOf(featureData.facilityId)
                if (index > -1) {
                  // console.log('translating--------', data, featureData)
                  coordinates.splice(index, 1, stationCoordinates)
                  lineGeometry.setCoordinates(coordinates)
                }
                return
              }
              // 移动节点
              if (data.to === featureData.id) {
                lineGeometry.setCoordinates([
                  ...coordinates.slice(0, coordinates.length - 1),
                  stationCoordinates
                ])
              }
              if (data.from === featureData.id) {
                lineGeometry.setCoordinates([
                  stationCoordinates,
                  ...coordinates.slice(1, coordinates.length)
                ])
              }
            })
            this.map.render()
          }
        })
        // 拖拽结束
        translate.on('translateend', ({ features }) => {
          this.dragging = false
          const feature = features.getArray()[0]
          // console.log('feature.values_', features)
          const featureData = feature.values_.data
          const position = feature
            .getGeometry()
            .getCoordinates()
            .map(i => changeDecimal(i, 6))
          this.locationChangeData[featureData.nodeId || featureData.facilityId] = {
            ...featureData,
            longitude: position[0],
            latitude: position[1]
          }
        })
      },
      modRegion(data, position) {
        const regionData = this.baseRegionList.find(i => i.regionId === data.nodeId)
        regionApi
          .mod({
            id: regionData.id,
            regionId: data.nodeId,
            longitude: position[0],
            latitude: position[1]
          })
          .then(rsp => {
            this.$emit('refresh')
          })
          .catch(() => {
            this.renderMap()
          })
      },
      leftClick() {
        this.map.on('click', evt => {
          if (this.isEdit || this.indexShowRight) return
          this.$store.commit('setGisActived', {
            cableIds: [],
            nodeIds: [],
            color: ''
          })
        })
      },
      // 右键点击
      rightClick() {
        this.map.getViewport().removeEventListener('contextmenu', this.rightClickEvent)
        this.map.getViewport().addEventListener('contextmenu', this.rightClickEvent)
      },
      rightClickEvent(event) {
        if (this.isEdit) return
        this.clearDrag()
        // console.log('rightClick', event)

        // 屏蔽自带的右键事件
        event.preventDefault()
        this.hideElCard()
        const mapBox = document.querySelector('#mapContainer').getBoundingClientRect()
        const layerX = event.clientX - mapBox.left
        const layerY = event.clientY - mapBox.top
        const features = this.map.getFeaturesAtPixel([layerX, layerY], {
          hitTolerance: 0
        })
        // console.log('contrightClickextmenu', features)

        const feature = features.find(i => i.values_.layerType === 'node')
        // console.log('contrightClickextmenu', feature)
        if (feature) {
          this.nodeSelected(feature.values_.data, layerX, layerY, 'stationRightClick')
          return
        }
        // const position = this.map.getCoordinateFromPixel([event.x, event.y])
        const position = this.map.getEventCoordinate(event)
        const location = [changeDecimal(position[0], 6), changeDecimal(position[1], 6)]
        const edgeFeature = features.find(i => i.values_.layerType === 'edge')
        if (edgeFeature) {
          // console.log('edgeFeature', edgeFeature)
          const edgeData = edgeFeature.values_.data
          this.$emit('selectEdge', {
            id: edgeData.id,
            mouseStatus: 'SELECT',
            clickProp: 'selectEdge',
            mouseEvent: 'selectEdge',
            currentEdge: {
              ...edgeData
            },
            coordinate: location,
            cableList: [edgeData],
            left: layerX,
            top: layerY
          })
        }
        // 要素不存在，证明点击的是地图空白处，就出现新增站点的按钮
        !feature &&
          !edgeFeature &&
          this.nodeSelected(
            {
              nodeId: '',
              longitude: location[0],
              latitude: location[1],
              coordinate: location
            },
            layerX,
            layerY,
            'mapRightClick'
          )
      },
      // 鼠标移入hover事件
      pointerHover() {
        this.map.on('pointermove', evt => {
          this.$emit('hoverEdge', {
            mouseStatus: 'LEAVE'
          })
          // if (this.dragging) return
          // console.log('pointermove', evt)
          this.mapHoverType = ''
          this.hoverLineFeature = null
          this.clusterInfo = this.$options.data().clusterInfo
          const features = this.map.getFeaturesAtPixel(evt.pixel, {
            hitTolerance: 0
          })
          if (!features.length) return
          if (this.zoom <= 10 && this.showType === 'home') {
            this.clusterInfo = {
              position: {
                top: evt.pixel_[1] + 10 + 'px',
                left: evt.pixel_[0] + 10 + 'px',
                display: 'block'
              },
              content: this.$t('CLUSTER_COUNT', { msg: features[0].get('features').length })
            }
            return
          }
          // console.log('this.isModLocation--------拖动中', features.map(i => i.values_.layerType))
          const nodeFeature = features.find(i => i.values_.layerType === 'node')
          if (nodeFeature) {
            // console.log('this.isModLocation--------拖动中')
            if (this.isModLocation) {
              this.addDraggedNode(nodeFeature)
              return
            }
            // console.log('nodeFeature', nodeFeature)
            const data = nodeFeature.values_.data
            if (data.facilityId) {
              this.mapHoverType = 'facilityHover'
              this.currentData = data
              this.hoverPosition = {
                left: evt.pixel_[0] + 5 + 'px', // 鼠标校准后的位置 140
                top: evt.pixel_[1] + 5 + 'px'
              }
            } else {
              this.$emit('hoverNode', {
                clickProp: 'hoverNode',
                mouseEvent: 'stationHover',
                mouseStatus: 'HOVER',
                left: evt.pixel_[0] + 5,
                top: evt.pixel_[1] + 5,
                currentNode: data,
                nodeId: data.nodeId
              })
            }
            return
          }
          if (this.showType === 'cableEidt') return
          const lineFeature = features.filter(i => i.values_.layerType === 'edge')
          // console.log('fiberHover-----------')
          if (lineFeature.length) {
            // console.log('pointermove', evt.coordinate)

            // console.log('lineFeature', lineFeature)
            const cableList = lineFeature.map(i => i.values_.data)
            const edgeData = cableList[0]
            // console.log('cableList', cableList)
            this.hoverLineFeature = lineFeature[0]
            this.$emit('hoverEdge', {
              id: edgeData.id,
              mouseStatus: 'HOVER',
              clickProp: 'hoverEdge',
              mouseEvent: 'fiberHover',
              currentEdge: {
                ...edgeData
                // positionIndex: this.findLngLatIndexAtLine(e.target, e.lnglat)
              },
              coordinate: evt.coordinate,
              cableList: cableList,
              left: evt.pixel_[0] - 10,
              top: evt.pixel_[1] - 10
            })
          }
        })
      },
      // 添加选中事件
      selectEvent() {
        const select = new Select({
          features: new Collection(),
          condition: click
        })
        this.map.addInteraction(select)
        select.on('select', event => {
          this.hideElCard()
          const feature = event.selected[0]
          // console.log('event', event)
          const selectedFeature = event.target.getFeatures()
          selectedFeature.clear()
          if (this.modifyLine) {
            this.unBindFacility(event.mapBrowserEvent.pixel_)
          }
          if (this.isEdit) return
          // event.target.getFeatures().clear()
          const x = event.mapBrowserEvent.pixel_[0]
          const y = event.mapBrowserEvent.pixel_[1]
          if (feature && feature.values_.layerType === 'node') {
            this.nodeSelected(feature.values_.data, x, y)
          }
        })
      },
      nodeSelected(data, x, y, type = null) {
        let mouseEvent = type || 'stationClick'
        if (data.facilityId && type) {
          mouseEvent = 'facilityClick'
        }
        if (data.facilityId && !type) return
        // if (!data) return
        this.$emit('selectNode', {
          ...data,
          ...{
            id: data.id,
            mouseStatus: 'SELECT',
            mouseEvent: mouseEvent,
            left: x - 3, // 减3是因为点击后鼠标还没移动到弹窗上面 弹窗就消失了 点不了操作按钮
            top: y - 3 // 适当调整下显示位置
          }
        })
      },
      // 点击定位按钮
      drawClick() {
        this.removeDraw()
        this.draw = new Draw({
          type: 'Point',
          source: new VectorSource()
        })
        this.draw.on('drawend', this.drawend)
        this.map.addInteraction(this.draw)
      },
      drawend({ feature }) {
        const coordinates = feature
          .getGeometry()
          // .transform('EPSG:3857', 'EPSG:4326')
          .getCoordinates()
        const location = {
          longitude: coordinates[0],
          latitude: coordinates[1]
        }
        this.$emit('located', location)
      },
      removeDraw() {
        this.draw && this.map.removeInteraction(this.draw)
        this.draw = null
      },
      hideElCard() {
        this.mapHoverType = ''
        this.$emit('selectNode', {
          mouseStatus: 'CANCEL'
        })
        this.$emit('selectEdge', {
          mouseStatus: 'CANCEL'
        })
      },
      // 地图的移动
      moveEvent() {
        this.map.on('moveend', e => {
          this.hideElCard()
          const zoom = this.map.getView().getZoom() // 获取当前地图的缩放级别
          this.zoom = zoom
        })
      },
      async fitView(data, times = 0) {
        if (this.isUpDate || !this.needFitView) return
        if (this.nodes.length === 0 && times < 4) {
          setTimeout(() => {
            this.fitView(data, times++)
          }, 500)
          return
        }
        const fitNodes = this.nodes.filter(i => data.includes(i.nodeId))
        if (fitNodes.length === 1) {
          return
        }
        const lngArr = []
        const latArr = []
        fitNodes.forEach(i => {
          lngArr.push(Number(i.longitude))
          latArr.push(Number(i.latitude))
        })
        await lngArr.sort((a, b) => a - b)
        await latArr.sort((a, b) => a - b)
        if (this.curZoom && this.selectedAll && this.$route.name === 'HOME') {
          this.zoom = this.curZoom.zoom
          this.map.getView().animate({
            center: this.curZoom.center, // 平移后的像素坐标转投影坐标
            duration: 0,
            zoom: this.zoom
          })
          this.$store.commit('setCurZoomView', null)
          return
        }
        this.map.getView().fit([lngArr.shift(), latArr.shift(), lngArr.pop(), latArr.pop()], {
          padding: this.viewPadding
        })
      },
      // /按像素平移地图
      panByPixel(centerLocation, mapCenter) {
        let center = centerLocation
        if (this.showType === 'home') {
          const centerpix = this.map.getPixelFromCoordinate(centerLocation) || [] // 投影坐标转为像素坐标
          const newx = centerpix[0] // 平移横坐标
          const newy = centerpix[1] + this.staticsItem.height / 2 + 20 // 平移纵坐标
          center = this.map.getCoordinateFromPixel([newx, newy])
        }
        const distance = getDistance(mapCenter, center)
        // console.log('distance', distance)
        if (distance < 500) return
        // console.log('this.zoom ', this.zoom)
        this.map.getView().animate({
          center: center, // 平移后的像素坐标转投影坐标
          duration: 1000
        })
      },
      changeMapType(data) {
        this.sourceType = data
        this.layerList.forEach(i => {
          i.layer.setVisible(data === i.type)
        })
      },
      changeZoom(count) {
        this.map.getView().animate({
          duration: 1000,
          zoom: this.zoom + count
        })
      },
      setCenter(center) {
        this.map.getView().animate({
          center: center, // 平移后的像素坐标转投影坐标
          duration: 1000,
          zoom: 16
        })
      },
      zoomChange() {
        // console.log('zoomChange', this.zoom)
        // this.cableLayer.setVisible(false)
        this.clusterLayer.setVisible(false)
        this.stationLayer.setVisible(false)
        this.facilityLayer.getSource().clear()
        if (this.zoom <= 10 && this.showType === 'home') {
          this.clusterLayer.setVisible(true)
          this.cableLayer.setVisible(false)
        } else {
          this.stationLayer.setVisible(true)
          this.cableLayer.setVisible(true)
        }
        // this.isModLocation && this.cableLayer.setVisible(false)
        if (this.zoom >= 12.8) {
          const facilityData = []
          this.facilityList.forEach(i => {
            (!this.layingMethodFilter.enable ||
              (this.layingMethodFilter.enable &&
                this.layingMethodFilter.facilityIds.includes(i.facilityId))) &&
              facilityData.push(this.createFacility(i, this.zoom >= 14.6))
          })
          this.facilityLayer.getSource().addFeatures(facilityData)
        }
        // !mapConfig.onlineMap && this.getOfflineData()
      },
      setNavPath(path) {
        // console.log('setNavPath', path)
        this.navLayer = this.creatLayerMap({ zIndex: 4 })
        const buttomPathStyle = new Style({
          stroke: new Stroke({
            color: [4, 110, 74],
            width: 8
          })
        })
        const upperPathStyle = new Style({
          stroke: new Stroke({
            color: [0, 186, 107],
            width: 4
          })
        })
        const pathFeature1 = this.createLineString({
          id: 'navPath1',
          path: path,
          label: ''
        })
        const pathFeature2 = this.createLineString({
          id: 'navPath2',
          path: path,
          label: ''
        })
        pathFeature1.setStyle(buttomPathStyle)
        pathFeature2.setStyle(upperPathStyle)
        this.navLayer.getSource().addFeature(pathFeature1)
        this.navLayer.getSource().addFeature(pathFeature2)
      },
      setFaultPoint(path, percent) {
        // console.log('percent', percent)
        percent = percent > 1 ? 1 : percent
        const lineString = new LineString(path)
        const point = lineString.getCoordinateAt(percent)
        this.$emit('faultReady', point)
        const faultPoint = this.createStation({
          nodeId: 'faultLocation',
          location: point,
          label: this.$t('FAULT_LOCATION_POINT'),
          status: 'faultPoint'
        })
        const lngArr = []
        const latArr = []
        path.forEach(i => {
          lngArr.push(Number(i[0]))
          latArr.push(Number(i[1]))
        })
        lngArr.sort((a, b) => a - b)
        latArr.sort((a, b) => a - b)
        this.map
          .getView()
          .fit([lngArr.shift(), latArr.shift(), lngArr.pop(), latArr.pop()], {
            padding: [30, 30, 30, 30]
          })
        this.stationLayer.getSource().addFeature(faultPoint)
      },
      showCableSegmentDetail(edge, operateType) {
        // console.log('showCableSegmentDetail', edge)
        this.cableSegmentOperateType = operateType
        this.cableData = {
          cableId: edge.cableId,
          cableName: edge.label,
          cableLength: edge.subInfo.length
        }
        const cableSegment = this.cableSegmentList.filter(i => i.cableId === edge.cableId)
        cableSegment.forEach(i => {
          const startPoint = this.facilityData[i.startPointId]
          const endPoint = this.facilityData[i.endPointId]
          i.startPointName = startPoint.label || startPoint.facilityName
          i.endPointName = endPoint.label || endPoint.facilityName
        })
        this.curCableSegment = cableSegment
        this.$store.commit('setFullScreen', true)
        this.cableSegmentShow = true
      },
      updateData(data) {
        this.cableSegmentShow = false
        if (data === true) {
          this.isUpDate = true
          this.getInfos()
        }
      },
      drawLine(data) {
        // console.log('drawLine', data)
        this.removeModifyLine()
        this.modifyData = data
        this.cableLayer.getSource().clear()
        const modifyStyle = new Style({
          stroke: new Stroke({
            color: '#45a7fc',
            lineDash: [6, 8],
            width: 4
          })
        })
        const modifyFeature = this.createLineString({
          id: 'modifyLine',
          path: data.path,
          label: ''
        })
        modifyFeature.setStyle(modifyStyle)
        const source = new VectorSource()
        source.addFeature(modifyFeature)
        this.cableLayer.getSource().addFeature(modifyFeature)
        this.modifyLine = new Modify({ source: source })
        this.modifyLine.on('modifystart', this.modifystart)
        this.modifyLine.on('modifyend', this.modifyend)
        this.map.addInteraction(this.modifyLine)
      },
      modifystart(event) {
        const facilityFeature = this.getModifyFacility(event)
        this.unBindFacilityData = null
        if (facilityFeature) {
          this.unBindFacilityData = facilityFeature.values_.data
        }
      },
      modifyend(event) {
        // console.log('modifyend', event)
        const facilityFeature = this.getModifyFacility(event)
        let path = {}
        if (facilityFeature) {
          const cableFeature = this.cableLayer.getSource().getFeatureById('modifyLine')
          const pathList = cableFeature.getGeometry().getCoordinates()
          const facilityData = facilityFeature.values_.data
          const difIndex = this.modifyData.path.findIndex(
            (i, index) => i[0] + '+' + i[1] !== pathList[index][0] + '+' + pathList[index][1]
          )
          pathList.splice(difIndex, 1, facilityData.location)
          if (this.unBindFacilityData) {
            this.modifyData.facilityIds = this.modifyData.facilityIds.filter(
              i => i !== this.unBindFacilityData.facilityId
            )
          }
          this.modifyData.facilityIds.splice(difIndex, 0, facilityData.facilityId)
          // console.log('this.modifyData', this.modifyData)
          path = {
            path: pathList
          }
        }
        this.drawLine({ ...this.modifyData, ...path })
      },
      getModifyFacility(event) {
        const mapBox = document.querySelector('#mapContainer').getBoundingClientRect()
        const offsetData = event.mapBrowserEvent.originalEvent
        const layerX = offsetData.clientX - mapBox.left
        const layerY = offsetData.clientY - mapBox.top
        const features = this.map.getFeaturesAtPixel([layerX, layerY], {
          hitTolerance: 0
        })
        const facilityFeature = features.find(
          i => i.values_.layerType === 'node' && i.values_.data.facilityId
        )
        return facilityFeature
      },
      unBindFacility(offsetData) {
        const features = this.map.getFeaturesAtPixel([offsetData[0], offsetData[1]], {
          hitTolerance: 0
        })
        // console.log('modifyData', this.modifyData)
        const facilityFeature = features.find(
          i =>
            i.values_.layerType === 'node' &&
            i.values_.data.facilityId &&
            this.modifyData.facilityIds.includes(i.values_.data.facilityId)
        )
        // console.log('facilityFeature', facilityFeature)

        if (!facilityFeature) return
        this.$confirm(this.$t('SURE_UNBIND_FACILITY'), { type: 'warning' })
          .then(() => {
            const facilityData = facilityFeature.values_.data
            // console.log('this.modi', this.modifyData)
            const facilityIndex = this.modifyData.facilityIds.indexOf(facilityData.facilityId)
            this.modifyData.facilityIds.splice(facilityIndex, 1)
            this.modifyData.path.splice(facilityIndex, 1)
            // console.log('facilityIndex', facilityIndex)
            this.drawLine({ ...this.modifyData })
            // this.$message.warning(this.$t('UPDATE_CABLE_SEGMENT'))
          })
          .catch(() => {})
      },
      removeModifyLine() {
        this.modifyLine && this.map.removeInteraction(this.modifyLine)
        this.modifyLine = null
        this.modifyData = null
      },
      getLineData() {
        const oldCableSegment = this.cableSegmentList.filter(
          k => this.modifyData.cableId === k.cableId
        )
        const cableSegments = []
        const facilityIds = this.modifyData.facilityIds
        facilityIds.forEach((i, index) => {
          if (index === 0) return
          const oldData =
            oldCableSegment.find(
              j => j.startPointId === facilityIds[index - 1] && j.endPointId === i
            ) || {}
          const startPoint = this.facilityData[facilityIds[index - 1]] || {}
          const endPoint = this.facilityData[i] || {}
          let distance = getDistance(
            [startPoint.longitude, startPoint.latitude],
            [endPoint.longitude, endPoint.latitude]
          )
          distance = changeDecimal(distance / 1000, 3)
          const item = {
            cableId: this.modifyData.cableId,
            startPointId: facilityIds[index - 1],
            startPointType: startPoint.facilityId ? 'FACILITY' : 'STATION',
            endPointId: i,
            endPointType: endPoint.facilityId ? 'FACILITY' : 'STATION',
            segmentName: oldData.segmentName || '',
            erectMethod: oldData.erectMethod || '',
            segmentLength: oldData.segmentLength || distance,
            sort: index
          }
          cableSegments.push(item)
        })
        return { cableId: this.modifyData.cableId, cableSegments: cableSegments, cableName: this.modifyData.label }
      },
      addDraggedNode(feature) {
        if (this.dragging === true) return
        // 鼠标滑动到当前要素（站点），让此站点可拖拽
        this.clearDrag(true)
        // console.log('addDraggedNode', feature)
        if (feature) {
          this.draggableCollection.push(feature)
          // this.dragging = true
        }
      },
      modlocation() {
        // this.cableLayer.setVisible(false)
        this.isModLocation = true
      },
      clearDrag(isModLocation = false) {
        this.draggableCollection && this.draggableCollection.clear()
        this.dragging = false
        this.isModLocation = isModLocation
        !isModLocation && (this.locationChangeData = {})
      }
    }
  }
</script>

<style lang="scss">
  @import '@/assets/css/mixin.module.scss';

  .map-switcher {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 1;
  }
  .openlayerMap {
    .ol-custom-overviewmap,
    .ol-custom-overviewmap.ol-uncollapsible {
      bottom: auto;
      left: auto;
      right: 0;
      bottom: 0;
    }

    .ol-custom-overviewmap:not(.ol-collapsed) {
      border: 1px solid black;
    }

    .ol-custom-overviewmap .ol-overviewmap-map {
      border: none;
      width: 300px;
    }

    .ol-custom-overviewmap .ol-overviewmap-box {
      border: 2px solid red;
    }

    .ol-custom-overviewmap:not(.ol-collapsed) button {
      bottom: auto;
      left: auto;
      right: 1px;
      bottom: 1px;
    }
    .ol-zoom {
      display: none;
    }
  }
  .cluster-prop {
    padding: 0 5px;
    line-height: 24px;
    border-radius: 4px;
    @include themeify {
      color: themed('multiFontColor');
      background: themed('homeTooltipBg');
      border: 1px solid themed('homeTooltipBorderColor');
    }
  }
  .zoom-tools {
    position: absolute;
    bottom: calc(33% + 25px);
    right: 20%;
    height: auto !important;
    width: 30px;
    z-index: 3;
    transition: all 0.5s;

    &.full-screen {
      bottom: 20px;
      right: 10px;
    }

    .tool-item {
      width: 25px;
      // height: 25px;
      text-align: center;
      line-height: 25px;
      font-size: 12px;
      @include themeify {
        background-color: themed('homeGridbg');
      }
    }
    .border-radus {
      border-radius: 3px;
    }

    .zoom-btn {
      font-size: 20px;
      overflow: hidden;
      .el-icon-plus {
        @include themeify {
          border-bottom: 1px solid themed('homeAxisSplitLine');
        }
      }
    }
  }
</style>
